package com.kgc.sbt.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.kgc.sbt.api.BuyVip;
import com.kgc.sbt.config.WxpayConfig;
import com.kgc.sbt.constant.WxpayConstant;
import com.kgc.sbt.service.BuyVipService;
import com.kgc.sbt.utils.HttpClient4Util;
import com.kgc.sbt.utils.WxpayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

/**
 * Created on 2021/8/10.
 * <p>
 * Author: songhe
 * <p>
 * Description:
 */
@Service
@Slf4j
public class BuyVipServiceImpl implements BuyVipService {

    @Autowired
    private WxpayConfig wxpayConfig;

    @Reference(timeout = 30000)
    private BuyVip buyVip;

    @Override
    public String getWxpayOrderParamsXml(String fromIp) throws Exception {

        // 要求参数的顺序必须按照字典序排列的，使用treemap
        Map<String, String> paramMap = new TreeMap<>();

        // 公共账号ID
        paramMap.put("appid", wxpayConfig.getAppId());
        // 商户号	mch_id
        paramMap.put("mch_id", wxpayConfig.getMchId());
        // 设备号 默认
        paramMap.put("device_info", "WEB");
        // 随机字符串	nonce_str
        paramMap.put("nonce_str", WxpayUtil.generateNonceStrUseRandom());

        //商品描述	body
        paramMap.put("body", "会员");

        // 商户订单号	out_trade_no
        paramMap.put("out_trade_no",WxpayUtil.generateOutTradeNo() );

        paramMap.put("total_fee","1");

        paramMap.put("spbill_create_ip", fromIp);

        // 签名	sign

        // 商品描述	body
        //商户订单号	out_trade_no
        // 通知地址	notify_url
        paramMap.put("notify_url", wxpayConfig.getNotifyUrl());
        // 交易类型	trade_type
        paramMap.put("trade_type", WxpayConstant.WEPAY_ORDER_NATIVE);

        // 商品ID 实际应该对应商品ID值
        paramMap.put("product_id", WxpayUtil.generateNonceStrUseUUID(9));

        // 签名处理，签名一般都是在最后进行，必须使用上面的所有参数
        // 注意：sign参数是不参与签名逻辑，但是它是接口参数，必须将此参数传给微信官方，微信官方根据上述参数重新签名，跟当前sign参数对比，确定请求是否可信
        paramMap.put("sign", WxpayUtil.generateSignature(paramMap,wxpayConfig.getMchKey()));

        // 将map参数转换为xml字符串格式返回
        return WxpayUtil.mapToXml(paramMap);
    }

    @Override
    public Map<String, String> sendToWxpayUnifiedOrder(String wxpayOrderXml) throws Exception {
        // 发送请求微信官方，统一下单
        String wxpayOrderReturnXml = HttpClient4Util.getResponse4PostByString(wxpayConfig.getOrderUrl(), wxpayOrderXml, WxpayConstant.WXPAY_EDCODING_UTF8);
        return WxpayUtil.xmlToMap(wxpayOrderReturnXml);
    }


    @Override
    public String getWxpayOrderQueryParamsXml(String outTradeNo) throws Exception {

        // 要求参数的顺序必须按照字典序排列的，使用treemap
        Map<String, String> paramMap = new TreeMap<>();

        // 公众账号ID	appid
        paramMap.put("appid", wxpayConfig.getAppId());
        // 商户号	mch_id
        paramMap.put("mch_id", wxpayConfig.getMchId());
        // 随机字符串	nonce_str
        paramMap.put("nonce_str", WxpayUtil.generateNonceStrUseRandom());

        // 微信订单号	transaction_id || 商户订单号	out_trade_no
        paramMap.put("out_trade_no", outTradeNo);

        // 签名	sign
        paramMap.put("sign", WxpayUtil.generateSignature(paramMap,wxpayConfig.getMchKey()));

        return WxpayUtil.mapToXml(paramMap);
    }

    @Override
    public Map<String, String> sendToWxpayQueryOrder(String queryOrderXml) throws Exception {
        String queryOrderReturnXml = HttpClient4Util.getResponse4PostByString(wxpayConfig.getQueryOrderUrl(), queryOrderXml, WxpayConstant.WXPAY_EDCODING_UTF8);
        return WxpayUtil.xmlToMap(queryOrderReturnXml);
    }

    @Override
    public String resolveWxpayResultNotify(String resultNotifyXml) throws Exception {
        //将微信官方回调的字符串xml转换为map集合
        Map<String,String> resultNotifyMap = WxpayUtil.xmlToMap(resultNotifyXml);

        //只需要处理回调成功的结果
        if (WxpayConstant.WXPAY_RETURN_CODE_SUCCESS.equals(resultNotifyMap.get("return_code"))){
            log.info("------ 3-1 微信官方异步通知支付结果：支付成功 ------");

            //必须要做签名校验（金额校验等）
            if (WxpayUtil.isSignatureValid(resultNotifyMap,wxpayConfig.getMchKey())){
                log.info("------ 3-2 微信官方异步通知签名校验，校验成功 ------");
                //TODO 进行对应业务逻辑处理，比如修改订单支付状态
                return WxpayConstant.WXPAY_RESPONSE_RESULT_SUCCESS;
            }

            // 签名校验失败
            log.info("------ 3-2 微信官方异步通知签名校验，校验失败 ------");
        }
        return WxpayConstant.WXPAY_RESPONSE_RESULT_FAIL;
    }




}
